package com.yanqu.road.server.manger.activity;

import com.yanqu.road.entity.activity.ActivityConditionInfo;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.UserActivityConditionData;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.player.UserInfo;
import com.yanqu.road.logic.bussiness.player.UserActivityBussiness;
import com.yanqu.road.server.TempMgr;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.manger.MonopolyMarketCommonMgr;
import com.yanqu.road.server.manger.player.UserMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.server.manger.rank.RankMgr;
import com.yanqu.road.server.pb.ActivityPb;
import com.yanqu.road.server.protocol.Protocol;

import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * @author ：zfr
 * @date ：2021/9/19 14:16
 */
public class MonopolyMarketRankActivityMgr extends TempMgr {

    private static Map<Integer, Map<Long, Map<Integer, List<UserActivityConditionData>>>> userActivityConditionDataMap;


    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        userActivityConditionDataMap = new ConcurrentHashMap<>();
        List<ActivityInfo> activityInfos = NormalActivityMgr.getOpenMonopolyMarketActivityList();
        List<Integer> activityIds = activityInfos.stream().map(ActivityInfo::getActivityId).collect(Collectors.toList());
        if (activityIds.size() > 0) {
            userActivityConditionDataMap = UserActivityBussiness.getActivityAllConditionData(activityIds);
        }
        return true;
    }

    public static List<UserActivityConditionData> getUserActivityConditionData(int activityId, long userId) {
        synchronized (userActivityConditionDataMap){
            List<UserActivityConditionData> list = new ArrayList<>();
            Map<Long, Map<Integer, List<UserActivityConditionData>>> userConditionMap = userActivityConditionDataMap.get(activityId);
            if (userConditionMap == null) {
                userActivityConditionDataMap.put(activityId, new ConcurrentHashMap<>());
                userConditionMap = userActivityConditionDataMap.get(activityId);
            }
            Map<Integer, List<UserActivityConditionData>> listMap = userConditionMap.get(userId);
            List<ActivityConditionInfo> activityConditionInfoList = NormalActivityMgr.getActivityConditionInfoList(activityId);
            if (listMap == null) {
                userConditionMap.put(userId, new ConcurrentHashMap<>());
                listMap = userConditionMap.get(userId);
            }
            for (ActivityConditionInfo activityConditionInfo : activityConditionInfoList) {
                if (activityConditionInfo.getType() > 0) {
                    if (isContinueAddCondition(activityConditionInfo.getType(), listMap.keySet())) {
                        if (listMap.get(activityConditionInfo.getType()) == null || !hasConditionData(listMap.get(activityConditionInfo.getType()), activityConditionInfo.getConditionId())) {
                            UserInfo userInfo = UserMgr.getUserInfo(userId);
                            //新的条件
                            UserActivityConditionData userConditionData = NormalActivityMgr.initUserActivityConditionData(userId, userInfo != null ? userInfo.getNickName() : "",
                                    BigInteger.ZERO, activityId, activityConditionInfo.getConditionId(), activityConditionInfo.getType());
                            addUserActivityConditionData(userConditionData);
                        }
                    }
                }
            }
            for (List<UserActivityConditionData> dataList : listMap.values()) {
                list.addAll(dataList);
            }
            return list;
        }
    }

    private static boolean isContinueAddCondition(int type, Set<Integer> conditionTypeList) {
        for (Integer conditionType : conditionTypeList) {
            if(conditionType == type){
                return false;
            }
        }
        return true;
    }

    //添加新的活动条件
    public static UserActivityConditionData addUserActivityConditionData(UserActivityConditionData userConditionData){
        synchronized (userActivityConditionDataMap){
            long userId = userConditionData.getUserId();
            int activityId = userConditionData.getActivityId();
            if(!userActivityConditionDataMap.containsKey(userConditionData.getActivityId())) {
                userActivityConditionDataMap.put(userConditionData.getActivityId(),new ConcurrentHashMap<>());
            }
            if (!userActivityConditionDataMap.get(activityId).containsKey(userId)) {
                userActivityConditionDataMap.get(activityId).put(userId, new ConcurrentHashMap<>());
            }
            if(!userActivityConditionDataMap.get(activityId).get(userId).containsKey(userConditionData.getType())){
                userActivityConditionDataMap.get(activityId).get(userId).put(userConditionData.getType(), new ArrayList<>());
            }
            if (!hasConditionData(userActivityConditionDataMap.get(activityId).get(userId).get(userConditionData.getType()), userConditionData.getConditionId())) {
                userActivityConditionDataMap.get(activityId).get(userId).get(userConditionData.getType()).add(userConditionData);
            }
            return getConditionData(userActivityConditionDataMap.get(activityId).get(userId).get(userConditionData.getType()), userConditionData);
        }
    }

    private static boolean hasConditionData(List<UserActivityConditionData> userActivityConditionDataList, int conditionInfoId) {
        return userActivityConditionDataList.stream().anyMatch(data -> data.getConditionId() == conditionInfoId);
    }

    private static UserActivityConditionData getConditionData(List<UserActivityConditionData> userActivityConditionDataList, UserActivityConditionData userConditionData) {
        for (UserActivityConditionData userActivityConditionData : userActivityConditionDataList) {
            if (userActivityConditionData.getConditionId() == userConditionData.getConditionId()) {
                return userActivityConditionData;
            }
        }
        return null;
    }

    /**
     * 榷场榜单加积分
     * @param playerId
     * @param addValue
     */
    public static void addRankValue(long playerId, long addValue){
        addRankValue(playerId,addValue,0,0,0);
    }

    /**
     * 榷场榜单加积分
     * @param playerId
     * @param addValue
     */
    public static void addRankValue(long playerId, long addValue,long time,long startTime,int type){
        MonopolyMarketRankActivityMgr.notifyRankEvent(playerId, eGamePlayerEventType.MonopolyMarketRank.getValue(), addValue,time,startTime,type);
    }

    /**
     * @param playerId
     * @param eventType
     * @param addValue
     * @param time 累计采集时间 s
     * @param startTime addValue 所采集的时间  0表示立刻获得的 s
     * @param type 资源类型
     */
    public static void notifyRankEvent(long playerId, int eventType, long addValue,long time,long startTime,int type) {
        synchronized (userActivityConditionDataMap) {
            if (addValue > 0) {
                List<ActivityInfo> activityList = NormalActivityMgr.getOpenMonopolyMarketActivityList();
                for (ActivityInfo activityInfo : activityList) {
                    if (!ActivityMgr.monopolyRankActivityCanAddTime(activityInfo)) {
                        continue;
                    }
                    if(time != 0 && activityInfo.getBeginTime() > startTime){
                        int cd = MonopolyMarketCommonMgr.getResGrabPointCD(type);
                        // 每个cd采集的数量
                        long rate = addValue / (time / cd);
                        // 采集的有效时长
                        long validTime = time - (activityInfo.getBeginTime() - startTime);
                        // 有效采集cd数
                        long i = validTime / cd;
                        addValue = rate * i;
                    }
                    Map<Long, Map<Integer, List<UserActivityConditionData>>> userConditionMap = userActivityConditionDataMap.get(activityInfo.getActivityId());
                    if (userConditionMap != null) {
                        List<UserActivityConditionData> conditionDataList = getUserActivityConditionData(activityInfo.getActivityId(), playerId);
                        if (conditionDataList != null) {
                            for (UserActivityConditionData conditionData : conditionDataList) {
                                if (conditionData.getType() == eventType) {
                                    if (conditionData.isGetReward()) {
                                        continue;
                                    }
                                    conditionData.setValue(conditionData.getValue().add(BigInteger.valueOf(addValue)));
                                    syncActivity(activityInfo.getActivityId(), conditionDataList, GamePlayerMgr.getOnlinePlayer(playerId)); // 同步客户端
                                    if (conditionData.getValue().compareTo(BigInteger.ZERO) > 0) {
                                        RankMgr.changeActivityRank(activityInfo.getActivityId(), playerId, conditionData.getValue(), conditionData.getParam());
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    private static void syncActivity(int activityId, List<UserActivityConditionData> userActivityConditionDataList, GamePlayer player) {
        if (null == player || null == userActivityConditionDataList) {
            return;
        }
        player.sendPacket(Protocol.U_ACTIVITY_SYNC, ActivityPb.syncActivityConditionData(activityId, userActivityConditionDataList));
    }

    @Override
    public boolean save() {
        for (Map<Long, Map<Integer, List<UserActivityConditionData>>> userConditionMap : userActivityConditionDataMap.values()) {
            for (Map<Integer, List<UserActivityConditionData>> conditionMap : userConditionMap.values()) {
                for (List<UserActivityConditionData> list : conditionMap.values()) {
                    for (UserActivityConditionData conditionData : list) {
                        if (conditionData.isInsertOption()) {
                            UserActivityBussiness.addUserActivityConditionData(conditionData);
                        } else if (conditionData.isUpdateOption()) {
                            UserActivityBussiness.updateUserActivityConditionData(conditionData);
                        }
                    }
                }
            }
        }
        return true;
    }

    @Override
    public boolean stop() {
        return true;
    }
}
